package org.yuanqiframework.yuanqi.boot.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.yuanqiframework.yuanqi.core.utils.StringUtils;
import org.yuanqiframework.yuanqi.web.exception.BusinessException;
import org.yuanqiframework.yuanqi.core.utils.BeanUtils;
import org.yuanqiframework.yuanqi.boot.sys.entity.SysDept;
import org.yuanqiframework.yuanqi.boot.sys.entity.SysUser;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysDeptMapper;
import org.yuanqiframework.yuanqi.boot.sys.mapper.SysUserMapper;
import org.yuanqiframework.yuanqi.boot.sys.service.SysDeptService;
import org.yuanqiframework.yuanqi.boot.sys.vo.SysDeptVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author cbt28
 * @description 针对表【sys_dept】的数据库操作Service实现
 * @createDate 2025-05-30 22:33:03
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept>
        implements SysDeptService {
    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private SysUserMapper sysUserMapper;

    @Override
    public boolean saveDept(SysDept sysDept) {
        sysDept.setId(StringUtils.getUUID());
        return sysDeptMapper.insert(sysDept) > 0;
    }

    @Override
    public boolean updateDept(SysDept sysDept) {
        String id = sysDept.getId();
        String deptName = sysDept.getDeptName();
        SysDept oldSysDept = sysDeptMapper.selectById(id);
        if (oldSysDept == null) {
            throw new BusinessException("该部门不存在！");
        }
        return sysDeptMapper.updateById(sysDept) > 0;
    }

    @Override
    public boolean removeDept(String id) {
        SysDept sysDept = sysDeptMapper.selectById(id);
        if (sysDept != null) {
            if (sysDept.getParentId() == null) {
                throw new BusinessException("该部门为根部门，不能删除！");
            }
        }
        List<String> childDeptIds = getChildDeptIds(id);
        //先查询该部门下是否有子部门
        if (sysDeptMapper.selectCount(new LambdaQueryWrapper<SysDept>()
                .eq(SysDept::getParentId, id)) > 0) {
            throw new BusinessException("该部门下有子部门，不能删除！");
        }
        if (sysUserMapper.selectCount(new LambdaQueryWrapper<SysUser>()
                .in(SysUser::getDeptId, id)) > 0) {
            throw new BusinessException("该部门下有用户，不能删除！");
        }
        return sysDeptMapper.deleteById(id) > 0;
    }

    @Override
    public List<SysDeptVO> listDept() {
        List<SysDept> sysDepts = sysDeptMapper.selectList(null);
        if (sysDepts == null || sysDepts.size() == 0) {
            return Collections.emptyList();
        }

        List<SysDeptVO> sysDeptVOs = sysDepts.stream().map(sysDept -> {
            SysDeptVO sysDeptVO = new SysDeptVO();
            BeanUtils.copyProperties(sysDept, sysDeptVO);
            return sysDeptVO;
        }).collect(Collectors.toList());

        // 获取所有顶级部门并排序
        List<SysDeptVO> topDepts = sysDeptVOs.stream()
                .filter(sysDeptVO -> sysDeptVO.getParentId() == null)
                .sorted(Comparator.comparingInt(SysDeptVO::getSortNum))
                .collect(Collectors.toList());

        // 递归设置子部门
        topDepts.forEach(topDept -> {
            findChildrenDept(topDept, sysDeptVOs);
        });

        return topDepts;
    }

    @Override
    public List<String> getChildDeptIds(String id) {
//        查询当前部门下的子孙部门id
        // 1. 获取所有部门数据
        List<SysDept> allDepts = sysDeptMapper.selectList(null);

        // 2. 转换为VO对象
        List<SysDeptVO> allDeptVOs = allDepts.stream()
                .map(dept -> {
                    SysDeptVO vo = new SysDeptVO();
                    BeanUtils.copyProperties(dept, vo);
                    return vo;
                })
                .collect(Collectors.toList());

        // 3. 查找目标部门
        SysDeptVO targetDept = allDeptVOs.stream()
                .filter(dept -> dept.getId().equals(id))
                .findFirst()
                .orElseThrow(() -> new BusinessException("部门不存在"));

        // 4. 递归收集所有子孙部门ID
        List<String> result = new ArrayList<>();
        result.add(targetDept.getId()); // 包含自身ID
        collectChildrenIds(targetDept, allDeptVOs, result);

        return result;
    }

    /**
     * 递归收集子部门ID
     */
    private void collectChildrenIds(SysDeptVO parentDept, List<SysDeptVO> allDepts, List<String> result) {
        List<SysDeptVO> children = allDepts.stream()
                .filter(dept -> parentDept.getId().equals(dept.getParentId()))
                .collect(Collectors.toList());

        for (SysDeptVO child : children) {
            result.add(child.getId());
            collectChildrenIds(child, allDepts, result);
        }
    }

    /**
     * 递归查找并设置子部门
     */
    private void findChildrenDept(SysDeptVO parentDept, List<SysDeptVO> allDepts) {
        List<SysDeptVO> children = allDepts.stream()
                .filter(dept -> parentDept.getId().equals(dept.getParentId()))
                .sorted(Comparator.comparingInt(SysDeptVO::getSortNum))
                .collect(Collectors.toList());

        if (!children.isEmpty()) {
            parentDept.setChildren(children);
            children.forEach(child -> findChildrenDept(child, allDepts));
        }
    }
}




